-module(mj_normal).
-include("common.hrl").

-export([check_start_hu/2,check_hu/3,check_normal_zm/3,check_normal_pao/4,check_jiang/1,check_jiang_258/1,check_qp/2,check_qys/2]).
-export([check_action/2,get_agangs_qp/1,get_agangs_peng/1,check_out/2,reset_field_id/0,get_snl_by_qp/1,
		 make_field/2,check_chi/3,check_qp/3]).

check_qp([],Ret) -> Ret;
check_qp([QP|Next],[]) -> check_qp(Next,[{QP,1}]);
check_qp([QP|Next],[{QP,Num}|Next1]) -> check_qp(Next,[{QP,Num + 1} | Next1]);
check_qp([QP|Next],[{QP1,Num}|Next1]) -> check_qp(Next,[{QP,1},{QP1,Num} | Next1]).

check_qp_jiang(102) -> true;
check_qp_jiang(105) -> true;
check_qp_jiang(108) -> true;
check_qp_jiang(202) -> true;
check_qp_jiang(205) -> true;
check_qp_jiang(208) -> true;
check_qp_jiang(302) -> true;
check_qp_jiang(305) -> true;
check_qp_jiang(308) -> true;
check_qp_jiang(_) -> false.

check_qp_wan(Data) when Data >= 101 andalso Data =< 109  -> true;
check_qp_wan(_)  -> false.

check_qp_tou(Data) when Data >= 201 andalso Data =< 209  -> true;
check_qp_tou(_)  -> false.

check_qp_tiao(Data) when Data >= 301 andalso Data =< 309  -> true;
check_qp_tiao(_)  -> false.

check_jiang_258(SNL) ->
	Pred1 =  fun({Qp,Num}) ->
					 Jiang = check_qp_jiang(Qp),
					 if
						 Num == 2 andalso Jiang == true -> true;
						 true -> false
					 end
			 end,
	case lists:filter(Pred1, SNL) of
		[{_,_},_] ->true;
		_ -> false
	end.
check_jiang(SNL) ->
	Pred1 =  fun({_,Num}) ->
					 if
						 Num == 2 -> true;
						 true -> false
					 end
			 end,
	case lists:filter(Pred1, SNL) of
		[{_,_} | _] -> true;
		_ -> false
	end.

check_hu(jjh,SNL,Filds) ->
	Pred =  fun({QP,_}) -> check_qp_jiang(QP) end,
	Pred1 =  fun(#pt_public_field_data{sort = Sort}) ->
					if
						Sort == ?FIELD_CHI -> false;
						true -> true
					end
			end,
	Pred2 =  fun(#pt_public_field_data{data = Data}) -> check_qp_jiang(Data div 10) end,
	case lists:partition(Pred, SNL) of
		{_,[]} ->
			case lists:partition(Pred1, Filds) of
				{_,[]} ->
					case lists:partition(Pred2, Filds) of
						{_,[]} -> true;
						_ -> false
					end;
				_ -> false
			end;
		_ -> false
	end;
check_hu(pph,SNL,Filds) ->
	Pred =  fun({_,Num}) ->
					if
						Num >= 3 -> true;
						true -> false
					end
			end,
	Pred1 =  fun({_,Num}) ->
					if
						Num == 2 -> true;
						true -> false
					end
			end,
	Pred2 =  fun(#pt_public_field_data{sort = Sort}) ->
					 if
						 Sort == ?FIELD_CHI -> false;
						 true -> true
					 end
			 end,
	
	Pred3 =  fun({Qp}) ->
					 case check_field(?FIELD_PENG,Qp,Filds) of
						 {ok,_} -> false;
						 _ -> true
					 end
			 end,
	
	case check_jiang(SNL) of
		true ->
			case lists:partition(Pred2, Filds) of
				{_,[]} ->
					case lists:partition(Pred, SNL) of
						{_,SNL1} ->
							case lists:partition(Pred1, SNL1) of
								{[{_,_}],SNL2} ->
									case lists:any(Pred3, SNL2) of
										true -> false;
										_ -> true
									end;
								_ -> false
							end;
						_ -> false
					end;
				_ -> false
			end;
		_ -> false
	end;
check_hu(qxd,SNL,[]) ->
	Pred =  fun({_,Num}) ->
					if
						Num == 2 -> true;
						true -> false
					end
			end,
	case lists:partition(Pred, SNL) of
		{_Qpd,[]} -> true;
		_ -> false
	end;
check_hu(_,_SNL,_Filds) -> false.

check_start_hu(dsx,SNL) ->
	case lists:keyfind(4, 2, SNL) of
		false -> false;
		_ -> true
	end;
check_start_hu(lls,SNL) ->
	Pred =  fun({_,Num}) ->
					if
						Num == 3 -> true;
						true -> false
					end
			end,
	LLSL = lists:filter(Pred, SNL),
	if
		erlang:length(LLSL) >= 2 -> true;
		true -> false
	end;
check_start_hu(bbh,SNL) ->
	Pred =  fun({QP,_}) -> check_qp_jiang(QP) end,
	case lists:any(Pred, SNL) of
		true -> false;
		_ -> true
	end;
check_start_hu(qys,SNL) ->
	Pred1 =  fun({QP,_}) -> check_qp_wan(QP) end,
	Pred2 =  fun({QP,_}) -> check_qp_tou(QP) end,
	Pred3 =  fun({QP,_}) -> check_qp_tiao(QP) end,
	case lists:any(Pred1, SNL) of
		true ->
			case lists:any(Pred2, SNL) of
				true ->
					case lists:any(Pred3, SNL) of
						true -> flase;
						_ -> true
					end;
				_ -> true
			end;
		_ -> true
	end;
check_start_hu(yzj,SNL) ->
	Pred =  fun({QP,_}) ->
					if
						QP >= 301 andalso QP =< 309 -> true;
						true -> false
					end
			end,
	case lists:filter(Pred, SNL) of
		[{301,1}] -> true;
		_ -> false
	end;
check_start_hu(yzh,SNL) ->
	Pred =  fun({QP,_}) -> check_qp_jiang(QP) end,
	case lists:filter(Pred, SNL) of
		[{205,1}] -> true;
		_ -> false
	end;
check_start_hu(_,_) -> false.

check_qp(Qp,Num,Qps) -> 
	L = lists:filter(fun(TQp) -> (TQp div 10) == (Qp div 10) end, Qps),
	Len = erlang:length(L),
	if
		Len >= Num ->
			GL = lists:sublist(L, Num),
			{ok,GL,Qps -- GL};
		true -> false
	end.

check_field(_Sort,_Data,[]) -> false;
check_field(Sort,Data,[Field | Nexts]) ->
	case Field of
		#pt_public_field_data{id = ID,sort = Sort,data = Data} -> {ok,ID};
		_ -> check_field(Sort,Data,Nexts)
	end.

reset_field_id() -> put(field_id,1).

get_field_id() ->
	Num = get(field_id),
	put(field_id,Num + 1),
	Num.

get_snl_by_qp(Qps) ->
	L = [Qp div 10||Qp <- Qps],
	SL = lists:sort(L),
	check_qp(SL,[]).

check_chi(Qp1,Qp2,Qp3) ->
	[NQp1,NQp2,NQp3] = lists:sort([Qp1,Qp2,Qp3]),
	if
		(NQp2 div 10) == ((NQp1 div 10) + 1) andalso (NQp3 div 10) == ((NQp2 div 10) + 1) -> {ok,NQp1,NQp2,NQp3};
		true -> false
	end.
		
make_field(?FIELD_PENG,Data) -> #pt_public_field_data{id = get_field_id(),sort = ?FIELD_PENG,data = Data};
make_field(?FIELD_AGANG,Data) -> #pt_public_field_data{id = get_field_id(),sort = ?FIELD_AGANG,data = Data};
make_field(?FIELD_MGANG,Data) -> #pt_public_field_data{id = get_field_id(),sort = ?FIELD_MGANG,data = Data};
make_field(?FIELD_CHI,Data) -> #pt_public_field_data{id = get_field_id(),sort = ?FIELD_CHI,data = Data};
make_field(_Action,_Data) -> {}.

get_agangs_qp({_Index,Qps,_Fields}) ->
	SNL = get_snl_by_qp(Qps),
	GQps = [NQp || {NQp,_} <- lists:filter(fun({_,Num}) -> Num == 4 end, SNL)],
	[[(GQp div 10) * 10 + 1,(GQp div 10) * 10 + 2,(GQp div 10) * 10 + 3,(GQp div 10) * 10 + 4] || GQp <- GQps].
get_agangs_peng({_Index,Qps,Fields}) ->
	PengFields = lists:filter(fun(Field) -> Field#pt_public_field_data.sort == ?FIELD_PENG end, Fields),
	Fun = fun(PengField,Gets) ->
				  case lists:filter(fun(Qp) -> (Qp div 10) == PengField#pt_public_field_data.data end, Qps) of
					  [FindQp] -> Gets ++ [{FindQp,PengField#pt_public_field_data.id}];
					  _ -> Gets
				  end
		  end,		
	lists:foldl(Fun, [], PengFields).

check_action({_Index,Qps,_Fields},{?ACTION_GAME_PENG,Data}) ->
	case check_qp(Data,2,Qps) of
		{ok,[Qp1,Qp2],NextQp} -> {ok,#pt_public_action_data{action = ?ACTION_GAME_PENG,action_data1 = Qp1,action_data2 = Qp2,action_data3 = Data},
									NextQp};
		_R -> false
	end;
check_action({Index,Qps,_Fields},{?ACTION_GAME_CHI,Data1,Data2}) ->
	#room_last{last_index = LastIndex,last_qp = LastQp} = get(room_last),
	Next = fun_room:check_next_index(Index,LastIndex),
	if
		Next == false -> false;
		true -> 
			case lists:filter(fun(Qp) -> (Qp div 10) == Data1 end, Qps) of
				[Qp1 | _] ->
					case lists:filter(fun(Qp) -> (Qp div 10) == Data2 end, Qps) of
						[Qp2 | _] ->
							case check_chi(Qp1,Qp2,LastQp) of
								{ok,_,_,_} -> {ok,#pt_public_action_data{action = ?ACTION_GAME_CHI,action_data1 = Qp1,action_data2 = Qp2,action_data3 = LastQp},
												 Qps -- [Qp1,Qp2]};
								_ -> false
							end;
						_ -> false
					end;
				_ -> false
			end
	end;
check_action({_Index,Qps,_Fields},{?ACTION_GAME_GANG,Data}) ->
	case check_qp(Data,3,Qps) of
		{ok,[Qp1,Qp2,Qp3],NextQp} -> {ok,#pt_public_action_data{action = ?ACTION_GAME_GANG,action_data1 = Qp1,action_data2 = Qp2,action_data3 = Qp3,action_data4 = Data},
										NextQp};
		_ -> false
	end;
check_action(_,_) -> false.

check_qys(L,Fields) -> 
	Fun = fun(Field,InL) ->
				  case Field of
					  #pt_public_field_data{data = Data} -> InL ++ [Data];
					  _ -> InL
				  end
		  end,
	LL = lists:foldl(Fun, L, Fields),
	[QP | _] = LL,
	SL = lists:sort(LL),
	SNL =  mj_normal:check_qp(SL,[]),
	
	S = QP div 100,
	Pred = fun({TQP,_}) ->
				   TS = TQP div 100,
				   TS == S
		   end,
	case lists:partition(Pred, SNL) of
		{_,[]} -> true;
		_ -> false
	end.

check_out(L,Qp) ->
	NL = L -- [Qp],
	if
		L == NL -> false;
		true -> {ok,NL}
	end.

check_fields(SNL,Fields) -> check_fields(SNL,Fields,0).
check_fields(SNL,Fields,OtherQp) ->
%% 	?debug("SNL = ~p",[SNL]),
	PengFields = lists:filter(fun(Field) -> Field#pt_public_field_data.sort == ?FIELD_PENG end, Fields),
	MGRet = lists:foldl(fun(Field = #pt_public_field_data{data = Data},Ret) ->
								 case lists:filter(fun({Qp,_}) -> Qp == Data end, SNL) of
									 [{OtherQp,_}] -> Ret;
									 [{Qp,_}] -> Ret ++ [{lists:keydelete(Qp, 1, SNL),(Fields -- [Field]) ++ [#pt_public_field_data{sort = ?FIELD_MGANG,data = Qp}]}];
									 _ -> Ret
								 end
						 end, [], PengFields),
	Ag = lists:filter(fun({_,Num}) -> Num == 4 end, SNL),
	AGRet = lists:foldl(fun({Qp,_},Ret) ->
								case Qp of
									OtherQp -> 
								 		Ret ++ [{lists:keydelete(Qp, 1, SNL),Fields ++ [#pt_public_field_data{sort = ?FIELD_MGANG,data = Qp}]}];
									_ -> 
										Ret ++ [{lists:keydelete(Qp, 1, SNL),Fields ++ [#pt_public_field_data{sort = ?FIELD_AGANG,data = Qp}]}]
								end
						 end, [], Ag),
	%%AAA
	PengRet1 = lists:foldl(fun({Qp,_},Ret) ->
								 Ret ++ [{lists:keydelete(Qp, 1, SNL) ++ [{Qp,1}],Fields ++ [#pt_public_field_data{sort = ?FIELD_PENG,data = Qp}]}]
						 end, [], Ag),
	Peng = lists:filter(fun({_,Num}) -> Num == 3 end, SNL),
	PengRet2 = lists:foldl(fun({Qp,_},Ret) ->
								 Ret ++ [{lists:keydelete(Qp, 1, SNL),Fields ++ [#pt_public_field_data{sort = ?FIELD_PENG,data = Qp}]}]
						 end, [], Peng),
	
	%%ABC
	ChiRet = lists:foldl(fun({Qp,Num},Ret) ->
							  case Num of
								  1 ->
%% 									  ?debug("Qp = ~p",[Qp]),
									  case lists:filter(fun({Qp1,_}) -> Qp1 == Qp + 1 end, SNL) of
										  [{Qp1,1}] ->
											  case lists:filter(fun({Qp2,_}) -> Qp2 == Qp + 2 end, SNL) of
												  [{Qp2,1}] ->
													  Ret ++ [{lists:keydelete(Qp2, 1, lists:keydelete(Qp1, 1, lists:keydelete(Qp, 1, SNL))),
															   Fields ++ [#pt_public_field_data{sort = ?FIELD_CHI,data = Qp}]}];
												  [{Qp2,Num2}] ->
													  Ret ++ [{lists:keydelete(Qp2, 1, lists:keydelete(Qp1, 1, lists:keydelete(Qp, 1, SNL))) ++ [{Qp2,Num2 -1}],
															   Fields ++ [#pt_public_field_data{sort = ?FIELD_CHI,data = Qp}]}];
												  _ -> Ret
											  end;
										  [{Qp1,Num1}] ->
											  case lists:filter(fun({Qp2,_}) -> Qp2 == Qp + 2 end, SNL) of
												  [{Qp2,1}] ->
													  Ret ++ [{lists:keydelete(Qp2, 1, lists:keydelete(Qp1, 1, lists:keydelete(Qp, 1, SNL))) ++ [{Qp1,Num1 -1}],
															   Fields ++ [#pt_public_field_data{sort = ?FIELD_CHI,data = Qp}]}];
												  [{Qp2,Num2}] ->
													  Ret ++ [{lists:keydelete(Qp2, 1, lists:keydelete(Qp1, 1, lists:keydelete(Qp, 1, SNL))) ++ [{Qp1,Num1 -1},{Qp2,Num2 -1}],
															   Fields ++ [#pt_public_field_data{sort = ?FIELD_CHI,data = Qp}]}];
												  _ -> Ret
											  end;
										  _ -> Ret
									  end;
								  _ ->
									  case lists:filter(fun({Qp1,_}) -> Qp1 == Qp + 1 end, SNL) of
										  [{Qp1,1}] ->
											  case lists:filter(fun({Qp2,_}) -> Qp2 == Qp + 2 end, SNL) of
												  [{Qp2,1}] ->
													  Ret ++ [{lists:keydelete(Qp2, 1, lists:keydelete(Qp1, 1, lists:keydelete(Qp, 1, SNL))) ++ [{Qp,Num -1}],
															   Fields ++ [#pt_public_field_data{sort = ?FIELD_CHI,data = Qp}]}];
												  [{Qp2,Num2}] ->
													  Ret ++ [{lists:keydelete(Qp2, 1, lists:keydelete(Qp1, 1, lists:keydelete(Qp, 1, SNL))) ++ [{Qp,Num -1},{Qp2,Num2 -1}],
															   Fields ++ [#pt_public_field_data{sort = ?FIELD_CHI,data = Qp}]}];
												  _ -> Ret
											  end;
										  [{Qp1,Num1}] ->
											  case lists:filter(fun({Qp2,_}) -> Qp2 == Qp + 2 end, SNL) of
												  [{Qp2,1}] ->
													  Ret ++ [{lists:keydelete(Qp2, 1, lists:keydelete(Qp1, 1, lists:keydelete(Qp, 1, SNL))) ++ [{Qp,Num -1},{Qp1,Num1 -1}],
															   Fields ++ [#pt_public_field_data{sort = ?FIELD_CHI,data = Qp}]}];
												  [{Qp2,Num2}] ->
													  Ret ++ [{lists:keydelete(Qp2, 1, lists:keydelete(Qp1, 1, lists:keydelete(Qp, 1, SNL))) ++ [{Qp,Num -1},{Qp1,Num1 -1},{Qp2,Num2 -1}],
															   Fields ++ [#pt_public_field_data{sort = ?FIELD_CHI,data = Qp}]}];
												  _ -> Ret
											  end;
										  _ -> Ret
									  end
							  end
					  end, [], SNL),
%% 	?debug("MGRet = ~p",[MGRet]),
%% 	?debug("AGRet = ~p",[AGRet]),
%% 	?debug("PengRet1 = ~p",[PengRet1]),
%% 	?debug("PengRet2 = ~p",[PengRet2]),
%% 	?debug("ChiRet = ~p",[ChiRet]),
	MGRet ++ AGRet ++ PengRet1 ++ PengRet2 ++ ChiRet.
	
check_normal_zm([{Jiang,2}],Filds,true) -> 
	case check_qp_jiang(Jiang) of
		true -> {true,Filds,Jiang};
		_ -> false
	end;
check_normal_zm([{Jiang,2}],Fields,_) -> {true,Fields,Jiang};
check_normal_zm(SNL,Filds,Jiang258) ->
%% 	?debug("{SNL,Filds,Jiang258} = ~p",[{SNL,Filds,Jiang258}]),
	ChexkFields = check_fields(SNL,Filds),
%% 	?debug("ChexkFields = ~p",[ChexkFields]),
	check_normal_zm(ChexkFields,Jiang258).

check_normal_zm([],_Jiang258) -> false;
check_normal_zm([{SNL,Fields} | Nexts],Jiang258) ->
	case check_normal_zm(SNL,Fields,Jiang258) of
		{true,NewFields,Jiang} -> {true,NewFields,Jiang};
		_ -> check_normal_zm(Nexts,Jiang258)
	end.

check_normal_pao([{Jiang,2}],Filds,_Qp,true) -> 
	case check_qp_jiang(Jiang) of
		true -> {true,Filds,Jiang};
		_ -> false
	end;
check_normal_pao([{Jiang,2}],Fields,_Qp,_) -> {true,Fields,Jiang};
check_normal_pao(SNL,Filds,Qp,Jiang258) ->
%% 	?debug("{SNL,Filds,Jiang258} = ~p",[{SNL,Filds,Jiang258}]),
	ChexkFields = check_fields(SNL,Filds,Qp),
%% 	?debug("ChexkFields = ~p",[ChexkFields]),
	check_normal_pao(ChexkFields,Qp,Jiang258).

check_normal_pao([],_Qp,_Jiang258) -> false;
check_normal_pao([{SNL,Fields} | Nexts],Qp,Jiang258) ->
	case check_normal_pao(SNL,Fields,Qp,Jiang258) of
		{true,NewFields,Jiang} -> {true,NewFields,Jiang};
		_ -> check_normal_pao(Nexts,Qp,Jiang258)
	end.